<template>
  <div class="device-monitoring-dashboard">
    <div class="header">
      <h1>CNC设备实时监控大屏</h1>
      <div class="status-indicators">
        <el-tag :type="connectionStatus === 'connected' ? 'success' : 'danger'">
          {{ connectionStatus === 'connected' ? '已连接' : '连接断开' }}
        </el-tag>
        <el-tag type="info">延迟: {{ latency }}ms</el-tag>
        <el-tag type="warning">在线设备: {{ onlineDeviceCount }}/{{ totalDeviceCount }}</el-tag>
      </div>
    </div>

    <div class="device-grid">
      <div 
        v-for="device in devices" 
        :key="device.deviceId"
        class="device-card"
        :class="getDeviceStatusClass(device.status)"
      >
        <div class="device-header">
          <h3>{{ device.deviceName }}</h3>
          <el-tag 
            :type="getStatusTagType(device.status)"
            class="status-tag"
          >
            {{ getStatusText(device.status) }}
          </el-tag>
        </div>

        <div class="device-info">
          <div class="info-row">
            <span class="label">产量:</span>
            <span class="value">{{ device.productionCount }}</span>
          </div>
          <div class="info-row">
            <span class="label">温度:</span>
            <span class="value">{{ device.temperature?.toFixed(1) }}°C</span>
          </div>
          <div class="info-row">
            <span class="label">转速:</span>
            <span class="value">{{ device.speed?.toFixed(0) }} RPM</span>
          </div>
          <div class="info-row">
            <span class="label">位置:</span>
            <span class="value">{{ device.location }}</span>
          </div>
        </div>

        <div v-if="device.alarmMessage" class="alarm-message">
          <el-alert
            :title="device.alarmMessage"
            type="error"
            :closable="false"
            size="small"
          />
        </div>

        <div class="last-update">
          最后更新: {{ formatTimestamp(device.timestamp) }}
        </div>
      </div>
    </div>

    <div class="statistics">
      <el-row :gutter="20">
        <el-col :span="6">
          <el-statistic title="总产量" :value="totalProduction" />
        </el-col>
        <el-col :span="6">
          <el-statistic title="运行设备" :value="runningDeviceCount" />
        </el-col>
        <el-col :span="6">
          <el-statistic title="报警设备" :value="alarmDeviceCount" />
        </el-col>
        <el-col :span="6">
          <el-statistic title="停机设备" :value="stoppedDeviceCount" />
        </el-col>
      </el-row>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { ElTag, ElAlert, ElStatistic, ElRow, ElCol } from 'element-plus'
import { DeviceMonitoringClient, type DeviceInfo, type DeviceStatusUpdate, DeviceStatus } from '../services/grpc/deviceMonitoring'
import moment from 'moment'

// 响应式数据
const devices = ref<DeviceInfo[]>([])
const connectionStatus = ref<'connected' | 'disconnected'>('disconnected')
const latency = ref<number>(0)
const clientId = ref<string>(`dashboard-${Date.now()}`)

// gRPC客户端
let grpcClient: DeviceMonitoringClient
let heartbeatInterval: number

// 计算属性
const totalDeviceCount = computed(() => devices.value.length)
const onlineDeviceCount = computed(() => 
  devices.value.filter(d => d.status !== DeviceStatus.UNKNOWN).length
)
const runningDeviceCount = computed(() => 
  devices.value.filter(d => d.status === DeviceStatus.RUNNING).length
)
const alarmDeviceCount = computed(() => 
  devices.value.filter(d => d.status === DeviceStatus.ALARM).length
)
const stoppedDeviceCount = computed(() => 
  devices.value.filter(d => d.status === DeviceStatus.STOPPED).length
)
const totalProduction = computed(() => 
  devices.value.reduce((sum, device) => sum + device.productionCount, 0)
)

// 方法
const initializeGrpcConnection = (): void => {
  grpcClient = new DeviceMonitoringClient(import.meta.env.VITE_APP_API_URL_WS)
  
  grpcClient.subscribeToDeviceStatus(
    clientId.value,
    handleDeviceStatusUpdate,
    handleConnectionError,
    handleConnectionEnd
  )

  // 启动心跳检测
  startHeartbeat()
}

const handleDeviceStatusUpdate = (update: DeviceStatusUpdate): void => {
  const serverTimestamp = update.serverTimestamp
  const clientTimestamp = Date.now()
  latency.value = clientTimestamp - serverTimestamp
  
  connectionStatus.value = 'connected'
  
  // 更新设备状态
  update.devices.forEach(deviceUpdate => {
    const existingIndex = devices.value.findIndex(d => d.deviceId === deviceUpdate.deviceId)
    
    if (existingIndex >= 0) {
      // 更新现有设备
      devices.value[existingIndex] = { ...deviceUpdate }
    } else {
      // 添加新设备
      devices.value.push({ ...deviceUpdate })
    }
  })
  
  console.log(`收到 ${update.devices.length} 个设备状态更新，延迟: ${latency.value}ms`)
}

const handleConnectionError = (error: any): void => {
  console.error('连接错误:', error)
  connectionStatus.value = 'disconnected'
}

const handleConnectionEnd = (): void => {
  console.log('连接结束')
  connectionStatus.value = 'disconnected'
}

const startHeartbeat = (): void => {
  heartbeatInterval = setInterval(async () => {
    try {
      const success = await grpcClient.sendHeartbeat(clientId.value)
      if (!success) {
        console.warn('心跳检测失败')
      }
    } catch (error) {
      console.error('心跳检测错误:', error)
    }
  }, 30000) // 每30秒发送一次心跳
}

const getDeviceStatusClass = (status: DeviceStatus): string => {
  switch (status) {
    case DeviceStatus.RUNNING: return 'status-running'
    case DeviceStatus.STOPPED: return 'status-stopped'
    case DeviceStatus.ALARM: return 'status-alarm'
    case DeviceStatus.MAINTENANCE: return 'status-maintenance'
    default: return 'status-unknown'
  }
}

const getStatusTagType = (status: DeviceStatus): 'success' | 'warning' | 'danger' | 'info' | 'primary' => {
  switch (status) {
    case DeviceStatus.RUNNING: return 'success'
    case DeviceStatus.STOPPED: return 'warning'
    case DeviceStatus.ALARM: return 'danger'
    case DeviceStatus.MAINTENANCE: return 'info'
    default: return 'primary'
  }
}

const getStatusText = (status: DeviceStatus): string => {
  switch (status) {
    case DeviceStatus.RUNNING: return '运行中'
    case DeviceStatus.STOPPED: return '停机'
    case DeviceStatus.ALARM: return '报警'
    case DeviceStatus.MAINTENANCE: return '维护'
    default: return '未知'
  }
}

const formatTimestamp = (timestamp: number): string => {
  return moment(timestamp).format('HH:mm:ss')
}

// 生命周期钩子
onMounted(() => {
  initializeGrpcConnection()
})

onUnmounted(() => {
  if (grpcClient) {
    grpcClient.disconnect()
  }
  if (heartbeatInterval) {
    clearInterval(heartbeatInterval)
  }
})
</script>

<style scoped>
.device-monitoring-dashboard {
  padding: 20px;
  background: linear-gradient(135deg, #1e3c72 0%, #2a5298 100%);
  min-height: 100vh;
  color: white;
}

.header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 30px;
  padding: 20px;
  background: rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  backdrop-filter: blur(10px);
}

.header h1 {
  margin: 0;
  font-size: 2.5em;
  font-weight: bold;
  text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
}

.status-indicators {
  display: flex;
  gap: 15px;
}

.device-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(350px, 1fr));
  gap: 20px;
  margin-bottom: 30px;
}

.device-card {
  background: rgba(255, 255, 255, 0.15);
  border-radius: 12px;
  padding: 20px;
  backdrop-filter: blur(10px);
  border: 2px solid transparent;
  transition: all 0.3s ease;
}

.device-card:hover {
  transform: translateY(-5px);
  box-shadow: 0 10px 25px rgba(0, 0, 0, 0.2);
}

.status-running {
  border-color: #67c23a;
  background: rgba(103, 194, 58, 0.2);
}

.status-stopped {
  border-color: #f56c6c;
  background: rgba(245, 108, 108, 0.2);
}

.status-alarm {
  border-color: #ff4757;
  background: rgba(255, 71, 87, 0.2);
  animation: pulse 2s infinite;
}

.status-maintenance {
  border-color: #409eff;
  background: rgba(64, 158, 255, 0.2);
}

.status-unknown {
  border-color: #909399;
  background: rgba(144, 147, 153, 0.2);
}

@keyframes pulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 71, 87, 0.7); }
  70% { box-shadow: 0 0 0 10px rgba(255, 71, 87, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 71, 87, 0); }
}

.device-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 15px;
}

.device-header h3 {
  margin: 0;
  font-size: 1.3em;
  font-weight: bold;
}

.device-info {
  margin-bottom: 15px;
}

.info-row {
  display: flex;
  justify-content: space-between;
  margin-bottom: 8px;
  font-size: 0.95em;
}

.label {
  font-weight: 500;
  opacity: 0.8;
}

.value {
  font-weight: bold;
  color: #fff;
}

.alarm-message {
  margin-bottom: 15px;
}

.last-update {
  font-size: 0.85em;
  opacity: 0.7;
  text-align: right;
}

.statistics {
  background: rgba(255, 255, 255, 0.1);
  border-radius: 12px;
  padding: 30px;
  backdrop-filter: blur(10px);
}

:deep(.el-statistic__content) {
  color: white !important;
}

:deep(.el-statistic__head) {
  color: rgba(255, 255, 255, 0.8) !important;
}
</style> 